package cn.coufran.springboot.starter.auth.config;

import cn.coufran.commons.Result;
import cn.coufran.springboot.starter.auth.AuthUser;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;

/**
 * 权限拦截插件，通过定义AuthAddition可以追加拦截规则
 * @param <D> 权限用户数据类型
 * @author Coufran
 * @version 1.0.0
 * @since 1.0.0
 */
public interface AuthAddition<D> {

    /**
     * 拦截请求
     * @param authUser 权限用户
     * @param request 请求对象
     * @param handler 请求处理方法
     * @throws AuthException 不允许请求时抛出异常
     */
    void authIntercept(AuthUser<D> authUser, HttpServletRequest request, Object handler) throws AuthException;

    /**
     * 权限拦截异常
     * @author Coufran
     * @since 1.0.0
     */
    class AuthException extends Exception {
        /** HTTP响应状态 */
        private HttpStatus httpStatus;
        /** 响应结果 */
        private Result result;

        /**
         * 构造拦截异常
         * @param httpStatus HTTP响应状态
         * @param result 响应结果
         */
        public AuthException(HttpStatus httpStatus, Result result) {
            this.httpStatus = httpStatus;
            this.result = result;
        }

        /**
         * 构造拦截异常
         * @param result 响应结果
         */
        public AuthException(Result result) {
            this(HttpStatus.FORBIDDEN, result);
        }

        /**
         * 构造拦截异常
         * @param msg 响应消息
         */
        public AuthException(String msg) {
            this(Result.error(40300, msg));
        }

        /**
         * 获取HTTP响应状态
         * @return HTTP响应状态
         */
        public HttpStatus getHttpStatus() {
            return httpStatus;
        }

        /**
         * 获取响应结果
         * @return 响应结果
         */
        public Result getResult() {
            return result;
        }
    }

}
